package com.aodao.sms.okhttp;

import com.alibaba.fastjson.JSONObject;
import okhttp3.*;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
 * 使用说明：
 * 1、需要修改对应的package路径
 * 2、添加fastjson依赖，也可以适当的修改为自己适用的json包依赖
     <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>fastjson</artifactId>
     <version>1.1.33.android</version>
     </dependency>
 * 3、添加okhttp3,maven依赖，理论上会兼容3.0以后的版本
     <dependency>
     <groupId>com.squareup.okhttp3</groupId>
     <artifactId>okhttp</artifactId>
     <version>3.0.0</version>
     </dependency>
 * 4、android调用同步方法sendMsgSync()建议使用子线程，避免使用ui线程，防止应用崩溃
 * 5、android调用异步方法sendMsgAsync()需要添加发送短信返回结果后业务处理逻辑（即todo位置）
 */

/**
 * Created by admin on 2017/6/21.
 */
public class SmsClient {
    private final String appId = ${appId};
    private final String appKey = ${appKey};
    private final String errCodeStr = ${errCodeStr};
    private final String apiUrl = "https://sms.aodao.com.cn/api/api.php";
    private JSONObject errCodeJson;


    /**
     * 同步调用发送短信，建议写在子线程里
     *
     * @param param
     * @return
     */
    public JSONObject sendMsgSync(JSONObject param) {
        try {
            if (param == null || param.size() == 0) {
                return error("缺少参数");
            } else {
                String token = randomStr();
                Long now = System.currentTimeMillis();

                JSONObject smsJson = new JSONObject();

                SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
                if (null != param.getString("name") && !"".equals(param.getString("name"))) {
                    smsJson.put("name", param.getString("name") + "_" + format.format(now) + "_" + token);
                } else {
                    smsJson.put("name", format.format(now) + "_" + token);
                }
                if (null != param.getString("sendtime") && !"".equals(param.getString("sendtime"))) {
                    smsJson.put("sendtime", param.getString("sendtime"));
                } else {
                    smsJson.put("sendtime", now / 1000 + "");
                }

                smsJson.put("appid", appId);
                smsJson.put("appkey", appKey);
                smsJson.put("mobile", param.getString("mobile"));
                smsJson.put("time", now / 1000 + "");
                smsJson.put("token", token);
                smsJson.put("sign", SHA1(MD5(token + now / 1000 + appKey + appId)));
                smsJson.put("inform_type", param.getString("inform_type"));
                smsJson.put("template_type", param.getString("template_type"));
                smsJson.put("typeid", param.getString("typeid"));
                smsJson.put("content_variable", param.get("content_variable"));
                String postData = "a=sendsms&agv=" + smsJson.toJSONString();

                System.out.println("apiUrl=" + apiUrl + ",postData=" + postData);
                String result = postSync(apiUrl, postData);
                JSONObject resultJson = JSONObject.parseObject(result);
                System.out.println("result:" + resultJson.toJSONString());
                if ("10021".equals(resultJson.getString("data"))) {
                    return resultJson;
                } else {
                    return error("接口异常");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 异步调用发送短信
     *
     * @param param
     * @return
     */
    public JSONObject sendMsgAsync(JSONObject param) {
        try {
            if (param == null || param.size() == 0) {
                return error("缺少参数");
            } else {
                String token = randomStr();
                Long now = System.currentTimeMillis();

                JSONObject smsJson = new JSONObject();

                SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
                if (null != param.getString("name") && !"".equals(param.getString("name"))) {
                    smsJson.put("name", param.getString("name") + "_" + format.format(now) + "_" + token);
                } else {
                    smsJson.put("name", format.format(now) + "_" + token);
                }
                if (null != param.getString("sendtime") && !"".equals(param.getString("sendtime"))) {
                    smsJson.put("sendtime", param.getString("sendtime"));
                } else {
                    smsJson.put("sendtime", now / 1000 + "");
                }

                smsJson.put("appid", appId);
                smsJson.put("appkey", appKey);
                smsJson.put("mobile", param.getString("mobile"));
                smsJson.put("time", now / 1000 + "");
                smsJson.put("token", token);
                smsJson.put("sign", SHA1(MD5(token + now / 1000 + appKey + appId)));
                smsJson.put("inform_type", param.getString("inform_type"));
                smsJson.put("template_type", param.getString("template_type"));
                smsJson.put("typeid", param.getString("typeid"));
                smsJson.put("content_variable", param.get("content_variable"));

                System.out.println("apiUrl=" + apiUrl + ",smsJson=" + smsJson);
                postAsync(apiUrl, smsJson.toJSONString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    private String randomStr() {
        return String.valueOf(Math.abs(new Random(System.currentTimeMillis()).nextLong()));
    }

    /**
     * 错误返回json
     *
     * @param errMsg
     * @return
     */
    private JSONObject error(String errMsg) {
        JSONObject error = new JSONObject();
        error.put("errno", -1);
        error.put("message", errMsg);
        return error;
    }

    /**
     * md5
     *
     * @param input
     * @return
     */
    private static String MD5(String input) {
        try {
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(input.getBytes());
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < md.length; i++) {
                String shaHex = Integer.toHexString(md[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * sha1
     *
     * @param decript
     * @return
     */
    private static String SHA1(String decript) {
        try {
            MessageDigest digest = java.security.MessageDigest
                    .getInstance("SHA-1");
            digest.update(decript.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 根据错误码获取错误信息
     *
     * @param code
     * @return
     */
    public String getMsgByCode(String code) {
        if (errCodeStr != null && !"".equals(errCodeStr) && errCodeJson == null) {
            errCodeJson = JSONObject.parseObject(errCodeStr);
            if (errCodeJson == null || errCodeJson.size() == 0) {
                return null;
            }
        }
        return errCodeJson.getString(code);
    }

    /**
     * 同步调用
     *
     * @param url
     * @param json
     * @return
     * @throws IOException
     */
    private String postSync(String url, String json) throws IOException {
        final MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .connectTimeout(5, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS).addInterceptor(new Interceptor() {
                    public Response intercept(Chain chain) throws IOException {
                        Request request = chain.request()
                                .newBuilder()
                                .build();
                        return chain.proceed(request);
                    }
                });
        OkHttpClient client = builder.build();

        RequestBody formBody = RequestBody.create(mediaType, json);
        Request request = new Request.Builder()
                .url(url)
                .post(formBody)
                .build();
        Response response = client.newCall(request).execute();

        if (response.isSuccessful()) {
            return response.body().string();
        } else {
            throw new IOException("发送短信失败：" + response);
        }
    }

    /**
     * 异步调用
     *
     * @param url
     * @param json
     * @throws IOException
     */
    private void postAsync(String url, String json) throws IOException {
        OkHttpClient client = new OkHttpClient();
        final MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
        FormBody.Builder builder = new FormBody.Builder();
        builder.add("a", "sendsms");
        builder.add("agv", json);
        RequestBody formBody = builder.build();
        Request request = new Request.Builder()
                .url(url)
                .post(formBody)
                .build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                //todo 返回json数据，写后续业务
                System.out.println(response.body().string());
            }
        });
    }
}
